/******************************************************************************* * Copyright (c) 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.ui.tests.concurrency; import org.eclipse.swt.widgets.Display; import org.eclipse.core.runtime.jobs.ILock; import org.eclipse.core.runtime.jobs.Job; import junit.framework.TestCase; /** * This tests the simple traditional deadlock of a thread holding a lock trying * to perform a syncExec, while the UI thread is waiting for that lock. * UISynchronizer and UILockListener conspire to prevent deadlock in this case. */ public class SyncExecWhileUIThreadWaitsForLock extends TestCase { public void testDeadlock() { final ILock lock = Job.getJobManager().newLock(); final boolean[] blocked = new boolean[] {false}; final boolean[] lockAcquired= new boolean[] {false}; Thread locking = new Thread("SyncExecWhileUIThreadWaitsForLock") { public void run() { try { //first make sure this background thread owns the lock lock.acquire(); //spawn an asyncExec that will cause the UI thread to be blocked Display.getDefault().asyncExec(new Runnable() { public void run() { blocked[0] = true; lock.acquire(); lock.release(); blocked[0] = false; } }); //wait until the UI thread is blocked waiting for the lock while (!blocked[0]) { try { Thread.sleep(100); } catch (InterruptedException e) { } } //now attempt to do a syncExec that also acquires the lock //this should succeed even while the above asyncExec is blocked, thanks to UISynchronizer Display.getDefault().syncExec(new Runnable() { public void run() { try { //use a timeout to avoid deadlock in case of regression if (lock.acquire(60000)) { //this flag is used to verify that we actually acquired the lock lockAcquired[0] = true; lock.release(); } } catch (InterruptedException e) { } } }); } finally { lock.release(); } } }; locking.start(); //wait until we succeeded to acquire the lock in the UI thread long waitStart = System.currentTimeMillis(); Display display = Display.getDefault(); while (!lockAcquired[0]) { //spin event loop so that asyncExed above gets run if (!display.readAndDispatch()) display.sleep(); //if we waited too long, fail the test if (System.currentTimeMillis()-waitStart > 60000) assertTrue("Deadlock occurred", false); } //if we get here, the test succeeded } }